home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / emacs / src / vmsmap.c < prev    next >
C/C++ Source or Header  |  1991-04-15  |  7KB  |  236 lines

  1. /* VMS mapping of data and alloc arena for GNU Emacs.
  2.    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
  3.    
  4. This file is part of GNU Emacs.
  5.  
  6. GNU Emacs is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU Emacs is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU Emacs; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Written by Mukesh Prasad.  */
  21.  
  22. #ifdef VMS
  23.  
  24. #include "config.h"
  25. #include "lisp.h"
  26. #include <rab.h>
  27. #include <fab.h>
  28. #include <rmsdef.h>
  29. #include <secdef.h>
  30.  
  31. /* RMS block size */
  32. #define    BLOCKSIZE    512
  33.  
  34. /* Maximum number of bytes to be written in one RMS write.
  35.  * Must be a multiple of BLOCKSIZE.
  36.  */
  37. #define    MAXWRITE    (BLOCKSIZE * 30)
  38.  
  39. /* This funniness is to ensure that sdata occurs alphabetically BEFORE the
  40.    $DATA psect and that edata occurs after ALL Emacs psects.  This is
  41.    because the VMS linker sorts all psects in a cluster alphabetically
  42.    during the linking, unless you use the cluster_psect command.  Emacs
  43.    uses the cluster command to group all Emacs psects into one cluster;
  44.    this keeps the dumped data separate from any loaded libraries. */
  45.  
  46. #ifdef __GNUC__
  47. /* We need a large sdata array because otherwise the impure storage will end up
  48.    in low memory, and this will screw up garbage collection (Emacs will not
  49.    be able to tell the difference between a string length and an address).
  50.    This array guarantees that the impure storage is at a sufficiently high
  51.    address so that this problem will not occur. */
  52. char sdata[8192] asm("_$$PsectAttributes_NOOVR$$$D$ATA") ;
  53. char edata[512]  asm("_$$PsectAttributes_NOOVR$$__DATA") ;
  54. #else
  55. globaldef {"$D$ATA"} char sdata[512]; /* Start of saved data area */
  56. globaldef {"__DATA"} char edata[512]; /* End of saved data area */
  57. #endif
  58.  
  59. /* Structure to write into first block of map file.
  60.  */
  61.  
  62. struct map_data
  63. {
  64.   char * sdata;            /* Start of data area */
  65.   char * edata;            /* End of data area */
  66.   int  datablk;            /* Block in file to map data area from/to */
  67. };
  68.  
  69. static void fill_fab (), fill_rab ();
  70. static int write_data ();
  71.  
  72. extern char *start_of_data ();
  73. extern int vms_out_initial;    /* Defined in malloc.c */
  74.  
  75. /* Maps in the data and alloc area from the map file.
  76.  */
  77.  
  78. int
  79. mapin_data (name)
  80.      char * name;
  81. {
  82.   struct FAB fab;
  83.   struct RAB rab;
  84.   int status, size;
  85.   int inadr[2];
  86.   struct map_data map_data;
  87.  
  88.  
  89.   /* Open map file. */
  90.   fab = cc$rms_fab;
  91.   fab.fab$b_fac = FAB$M_BIO|FAB$M_GET;
  92.   fab.fab$l_fna = name;
  93.   fab.fab$b_fns = strlen (name);
  94.   status = sys$open (&fab);
  95.   if (status != RMS$_NORMAL)
  96.     {
  97.       printf ("Map file not available, running bare Emacs....\n");
  98.       return 0;            /* Map file not available */
  99.     }
  100.   /* Connect the RAB block */
  101.   rab = cc$rms_rab;
  102.   rab.rab$l_fab = &fab;
  103.   rab.rab$b_rac = RAB$C_SEQ;
  104.   rab.rab$l_rop = RAB$M_BIO;
  105.   status = sys$connect (&rab);
  106.   if (status != RMS$_NORMAL)
  107.     lib$stop (status);
  108.   /* Read the header data */
  109.   rab.rab$l_ubf = (char *) &map_data;
  110.   rab.rab$w_usz = sizeof (map_data);
  111.   rab.rab$l_bkt = 0;
  112.   status = sys$read (&rab);
  113.   if (status != RMS$_NORMAL)
  114.     lib$stop (status);
  115.   status = sys$close (&fab);
  116.   if (status != RMS$_NORMAL)
  117.     lib$stop (status);
  118.   if (map_data.sdata != start_of_data ())
  119.     {
  120.       printf ("Start of data area has moved: cannot map in data.\n");
  121.       return 0;
  122.     }
  123.   if (map_data.edata != edata)
  124.     {
  125.       printf ("End of data area has moved: cannot map in data.\n");
  126.       return 0;
  127.     }
  128.   fab.fab$l_fop |= FAB$M_UFO;
  129.   status = sys$open (&fab);
  130.   if (status != RMS$_NORMAL)
  131.     lib$stop (status);
  132.   /* Map data area. */
  133.   inadr[0] = (int) map_data.sdata;
  134.   inadr[1] = (int) map_data.edata;
  135.   status = sys$crmpsc (inadr, 0, 0, SEC$M_CRF | SEC$M_WRT, 0, 0, 0,
  136.                fab.fab$l_stv, 0, map_data.datablk, 0, 0);
  137.   if (! (status & 1))
  138.     lib$stop (status);
  139. }
  140.  
  141. /* Writes the data and alloc area to the map file.
  142.  */
  143. mapout_data (into)
  144.      char * into;
  145. {
  146.   struct FAB fab;
  147.   struct RAB rab;
  148.   int status;
  149.   struct map_data map_data;
  150.   int datasize, msize;
  151.  
  152.   if (vms_out_initial)
  153.     {
  154.       error ("Out of initial allocation. Must rebuild emacs with more memory (VMS_ALLOCATION_SIZE).");
  155.       return 0;
  156.     }
  157.   map_data.sdata = start_of_data ();
  158.   map_data.edata = edata;
  159.   datasize = map_data.edata - map_data.sdata + 1;
  160.   map_data.datablk = 2 + (sizeof (map_data) + BLOCKSIZE - 1) / BLOCKSIZE;
  161.   /* Create map file. */
  162.   fab = cc$rms_fab;
  163.   fab.fab$b_fac = FAB$M_BIO|FAB$M_PUT;
  164.   fab.fab$l_fna = into;
  165.   fab.fab$b_fns = strlen (into);
  166.   fab.fab$l_fop = FAB$M_CBT;
  167.   fab.fab$b_org = FAB$C_SEQ;
  168.   fab.fab$b_rat = 0;
  169.   fab.fab$b_rfm = FAB$C_VAR;
  170.   fab.fab$l_alq = 1 + map_data.datablk +
  171.               ((datasize + BLOCKSIZE - 1) / BLOCKSIZE);
  172.   status = sys$create (&fab);
  173.   if (status != RMS$_NORMAL)
  174.     {
  175.       error ("Could not create map file");
  176.       return 0;
  177.     }
  178.   /* Connect the RAB block */
  179.   rab = cc$rms_rab;
  180.   rab.rab$l_fab = &fab;
  181.   rab.rab$b_rac = RAB$C_SEQ;
  182.   rab.rab$l_rop = RAB$M_BIO;
  183.   status = sys$connect (&rab);
  184.   if (status != RMS$_NORMAL)
  185.     {
  186.       error ("RMS connect to map file failed");
  187.       return 0;
  188.     }
  189.   /* Write the header */
  190.   rab.rab$l_rbf = (char *) &map_data;
  191.   rab.rab$w_rsz = sizeof (map_data);
  192.   status = sys$write (&rab);
  193.   if (status != RMS$_NORMAL)
  194.     {
  195.       error ("RMS write (header) to map file failed");
  196.       return 0;
  197.     }
  198.   if (! write_data (&rab, map_data.datablk, map_data.sdata, datasize))
  199.     return 0;
  200.   status = sys$close (&fab);
  201.   if (status != RMS$_NORMAL)
  202.     {
  203.       error ("RMS close on map file failed");
  204.       return 0;
  205.     }
  206.   return 1;
  207. }
  208.  
  209. static int
  210. write_data (rab, firstblock, data, length)
  211.      struct RAB * rab;
  212.      char * data;
  213. {
  214.   int status;
  215.   
  216.   rab->rab$l_bkt = firstblock;
  217.   while (length > 0)
  218.     {
  219.       rab->rab$l_rbf = data;
  220.       rab->rab$w_rsz = length > MAXWRITE ? MAXWRITE : length;
  221.       status = sys$write (rab, 0, 0);
  222.       if (status != RMS$_NORMAL)
  223.     {
  224.       error ("RMS write to map file failed");
  225.       return 0;
  226.     }
  227.       data = &data[MAXWRITE];
  228.       length -= MAXWRITE;
  229.       rab->rab$l_bkt = 0;
  230.     }
  231.   return 1;
  232. }                /* write_data */
  233.  
  234. #endif /* VMS */
  235.  
  236.